<?php
namespace app\service;

use Firebase\JWT\JWT;
use Firebase\JWT\Key;
use think\facade\Config;

class JwtService
{
    // 秘钥
    private static $key;
    // 签发者
    private static $issuer;
    // 有效期
    private static $expire;
    
    // 初始化配置
    public static function init()
    {
        $config = Config::get('jwt');
        self::$key = $config['key'];
        self::$issuer = $config['issuer'];
        self::$expire = $config['expire'];
    }
    
    /**
     * 生成JWT Token
     * @param array $data 用户数据
     * @param int $type 登录类型(1:web,2:app,3:小程序)
     * @return string
     */
    public static function generateToken(array $data, int $type = 1): string
    {
        self::init();
        
        $time = time();
        $payload = [
            'iss' => self::$issuer,        // 签发者
            'iat' => $time,               // 签发时间
            'exp' => $time + self::$expire, // 过期时间
            'data' => [
                'user_id' => $data['id'],
                'username' => $data['username'],
                'login_type' => $type
            ]
        ];
        
        return JWT::encode($payload, self::$key, 'HS256');
    }
    
    /**
     * 验证JWT Token
     * @param string $token
     * @return array
     * @throws \Exception
     */
    public static function verifyToken(string $token): array
    {
        self::init();
        
        try {
            $decoded = JWT::decode($token, new Key(self::$key, 'HS256'));
            return (array)$decoded;
        } catch (\Exception $e) {
            throw new \Exception('Token验证失败: ' . $e->getMessage());
        }
    }
    
    /**
     * 刷新Token
     * @param string $token
     * @return string
     * @throws \Exception
     */
    public static function refreshToken(string $token): string
    {
        $data = self::verifyToken($token);
        $payload = (array)$data['data'];
        return self::generateToken($payload, $payload['login_type']);
    }
    
    /**
     * 获取Token中的用户ID
     * @param string $token
     * @return int
     * @throws \Exception
     */
    public static function getUserId(string $token): int
    {
        $data = self::verifyToken($token);
        return $data['data']->user_id;
    }
}